<template>
    <a-dropdown
        :popPlacement="popPlacement"
        :useTargetWidth="true"
        :maxHeight="maxHeight"
        class="a-input-search"
        v-model:popShown="popShown"
        :trigger="'none'"
        ref="popup"
    >
        <a-control-group>
            <a-input-string
                class="c-w-100"
                :color="myColor"
                :size="mySize"
                :sharp="mySharp"
                :disabled="myDisabled"
                v-model:value="displayText"
                :placeholder="placeholder"
                :clearable="clearable"
                :isInner="true"
                @click="popShown = true"
                @clear="input(null)"
            ></a-input-string>
            <a-button
                v-if="attachButtonShown"
                class="c-f-shrink-0"
                :color="myColor"
                :size="mySize"
                :sharp="mySharp"
                :disabled="myDisabled"
                :square="true"
                ref="btn"
                @click="search(changeId)"
                ><span class="fa fa-fw fa-search"></span></a-button
        ></a-control-group>

        <template v-slot:pop>
            <a-control-group
                direction="v"
                :block="true"
                class="pop"
                :class="[
                    !mySharp ? `c-round-${mySize}` : '',
                    ` c-shadow-${mySize}`,
                ]"
            >
                <a-input-check-box-single
                    :color="myColor"
                    :size="mySize"
                    :sharp="mySharp"
                    :disabled="myDisabled || getDisabledFunc(a)"
                    :block="true"
                    :plain="true"
                    v-for="a in items"
                    :key="getTextFunc(a)"
                    @click="clickItem(a)"
                    :value="value == getValueFunc(a)"
                    class="c-f-h c-f-between-center c-f-shrink-0"
                >
                    <template v-slot:prepend>
                        <span>{{ getTextFunc(a) }}</span>
                    </template>
                    <template v-slot:checkedFlag>
                        <span class="fa fa-fw fa-check"></span>
                    </template>
                    <template v-slot:unCheckedFlag>
                        <span></span>
                    </template>
                </a-input-check-box-single>
            </a-control-group>
        </template>
    </a-dropdown>
</template>

<style lang="scss" scoped>
@import "../scss/vars";

.pop {
    background-color: $defaultBgColor;
}
</style>

<script>
import AInputString from './AInputString.vue'
import AControlGroup from './AControlGroup.vue'
import ADropdown from './ADropdown.vue'
import AInputCheckBoxSingle from './AInputCheckBoxSingle.vue'
import inputMixin from "../mixins/inputMixin"
import selectMixin from '../mixins/selectMixin'
import utils from '../common/utils'

export default {
    name: 'AInputSearch',
    components: { AInputString, AControlGroup, ADropdown, AInputCheckBoxSingle },
    mixins: [inputMixin, selectMixin],
    emits: ['focus', 'blur', 'itemClick'],
    props: {
        value: null,
        searchFunc: {
            type: Function,
            default: async (displayText) => [],
        },
        delay: {
            type: Number,
            default: 0,
        },
        getTextFunc: {
            type: Function,
            default: a => a.text,
        },
        getValueFunc: {
            type: Function,
            default: a => a.value,
        },
        getDisabledFunc: {
            type: Function,
            default: a => a.disabled,
        },
        getDisplayTextByValueFunc: {
            type: Function,
            default: null,
        },
        /**
         * 对齐到target的位置
         */
        popPlacement: {
            type: String,
            default: 'bottom'
        },
        clearable: {
            type: Boolean,
            default: true,
        },
        maxHeight: {
            type: Number,
            default: null
        },
        placeholder: {
            type: String,
            default: null
        },
        attachButtonShown: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        return {
            popShown: false,
            displayText: null,
            changeId: 0,
            items: []
        }
    },
    async mounted() {
        if (this.getDisplayTextByValueFunc && this.value != null) {
            this.displayText = await this.getDisplayTextByValueFunc(this.value)
        }
    },
    watch: {
        async displayText() {
            let changeId = ++this.changeId
            if (this.delay) {
                await utils.sleep(this.delay)
                if (this.changeId != changeId) {
                    return
                }
            }
            await this.search(changeId)
        },
        async value() {
            if (this.changeId == 0) {
                if (this.getDisplayTextByValueFunc && this.value != null) {
                    this.displayText = await this.getDisplayTextByValueFunc(this.value)
                    return
                }
            }
            let selectedItem = this.items.find(a => this.getValueFunc(a) == this.value)
            if (selectedItem) {
                this.displayText = this.getTextFunc(selectedItem)
            } else {
                this.displayText = null
            }
        },
    },
    methods: {
        input(val) {
            this.$emit('update:value', val)
        },
        clickItem(item) {
            let displayText = this.getTextFunc(item)
            this.displayText = displayText
            this.input(this.getValueFunc(item))
            this.$emit('itemClick', item)
            this.popShown = false
        },
        getInputEl() {
            return this.$refs.popup.getTargetEl()
        },
        async search(changeId) {
            let items = await this.searchFunc(this.displayText)
            if (this.changeId != changeId) {
                return
            }
            this.items = items
            if (items.length && this.getInputEl().contains(window.document.activeElement)) {
                this.popShown = true
            }
        }
    },
}
</script>